﻿using ImageCompare.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Windows.Forms;


namespace ImageCompare
{
    public partial class Form1 : Form
    {
        private static List<FileInfo> files;
        private static DataTable dt;
        private static Thread thread = null;
        private static DataGridView dgv;
        private static ListBox _listbox;
        public delegate void GetGridCallBack(DataGridView dgv, DataTable dt);
        public static void GetGrid(DataGridView dgv,DataTable dt)
        {
            if (dgv.InvokeRequired)
            {
                GetGridCallBack getGridCallBack = GetGrid;
                dgv.Invoke(getGridCallBack, new object[] { dgv,dt });
            }
            dgv.DataSource = dt;            
        }
        public Form1()
        {
            InitializeComponent();
            dt = new DataTable();
            DataColumn colums = new DataColumn();
            colums = dt.Columns.Add("原文件");
            colums = dt.Columns.Add("重复文件");
            _listbox = this.listBox1;
        }

        private void btn_Dir_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fd = new FolderBrowserDialog();
            if (fd.ShowDialog() == DialogResult.OK)
            {
                txt_imagePath.Text = fd.SelectedPath;                
            }
        }

        public static void Compare()
        {            
            ShowMsg.showMsg(_listbox, DateTime.Now + "-开始对比");
            int cnt = files.Count;
            int num = 0;
            ShowMsg.showMsg(_listbox, "共需要对比" + cnt * (cnt - 1) / 2 + "条");
            for (int i = 0; i < cnt; i++)
            {
                FileStream fs1 = new FileStream(files[i].FullName, FileMode.Open);
                MemoryStream ms1 = new MemoryStream();
                Image img1 = Image.FromStream(fs1);
                img1.Save(ms1, System.Drawing.Imaging.ImageFormat.Jpeg);
                String Base64_1 = Convert.ToBase64String(ms1.ToArray());
                for(int j = i+1; j < files.Count; j++)
                {
                    FileStream fs2 = new FileStream(files[j].FullName, FileMode.Open);
                    MemoryStream ms2 = new MemoryStream();
                    Image img2 = Image.FromStream(fs2);
                    img2.Save(ms2, System.Drawing.Imaging.ImageFormat.Jpeg);
                    String Base64_2 = Convert.ToBase64String(ms2.ToArray());
                    if(Base64_1.Equals(Base64_2))
                    {
                        DataRow dr = dt.NewRow();
                        dr["原文件"] = files[i].Name;
                        dr["重复文件"] = files[j].Name;
                        dt.Rows.Add(dr);
                    }
                    ms2.Close();
                    fs2.Close();
                    img2.Dispose();
                    num++;

                    ShowMsg.showMsg(_listbox, "已对比" + num + "/" + cnt * (cnt - 1) / 2 + "次");
                }
                ms1.Close();
                fs1.Close();
                img1.Dispose();
            }            
            if (dt.Rows.Count > 0)
            {
                ShowMsg.showMsg(_listbox, DateTime.Now + "-对比完成，共计发现重复文件" + dt.Rows.Count + "对");
                GetGrid(dgv, dt);
            }
            else
                ShowMsg.showMsg(_listbox, DateTime.Now + "-对比完成，未发现重复图片");
        }


        private void btn_compare_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txt_imagePath.Text))
            {
                MessageBox.Show("请先选择图片所在文件夹");
                return;
            }
            files = PublicMethod.GetPicFiles(txt_imagePath.Text);
            dgv = this.dataGridView1;
            lb_Cnt.Text = "共计" + files.Count + "条";
            if (files.Count > 1)
            {
                thread = new Thread(Compare);
                thread.IsBackground = true;
                thread.Start();              
            }
        }

        //大致比较
        public static bool ImageCompareString(Image firstImage, Image secondImage)
        {
            MemoryStream ms = new MemoryStream();
            firstImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            String firstBitmap = Convert.ToBase64String(ms.ToArray());
            ms.Position = 0;            

            secondImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            String secondBitmap = Convert.ToBase64String(ms.ToArray());

            if (firstBitmap.Equals(secondBitmap))
            {
                return true;
            }
            else
            {
                return false;
            }
        }  

        //精确比较
        public bool IsSameImg(Bitmap img, Bitmap bmp)
        {
            //大小一致
            if (img.Width == bmp.Width && img.Height == bmp.Height)
            {
                //将图片一锁定到内存
                BitmapData imgData_i = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                IntPtr ipr_i = imgData_i.Scan0;
                int length_i = imgData_i.Width * imgData_i.Height * 3;
                byte[] imgValue_i = new byte[length_i];
                Marshal.Copy(ipr_i, imgValue_i, 0, length_i);
                img.UnlockBits(imgData_i);
                //将图片二锁定到内存
                BitmapData imgData_b = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                IntPtr ipr_b = imgData_b.Scan0;
                int length_b = imgData_b.Width * imgData_b.Height * 3;
                byte[] imgValue_b = new byte[length_b];
                Marshal.Copy(ipr_b, imgValue_b, 0, length_b);
                img.UnlockBits(imgData_b);
                //长度不相同
                if (length_i != length_b)
                {
                    return false;
                }
                else
                {
                    //循环判断值
                    for (int i = 0; i < length_i; i++)
                    {
                        //不一致
                        if (imgValue_i[i] != imgValue_b[i])
                        {
                            return false;
                        }
                    }
                    return true;
                }
            }
            else
            {
                return false;
            }
        }

        private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dt.Rows.Count > 0)
            {
                int row = e.RowIndex;
                int column = e.ColumnIndex;
                string filePath = txt_imagePath.Text;
                string fileName = this.dataGridView1[column, row].Value.ToString();
                string fullPath = Path.Combine(filePath, fileName);
                if (File.Exists(fullPath))
                    System.Diagnostics.Process.Start("Explorer.exe", "/select," + fullPath);
            }
            else
                ShowMsg.showMsg(listBox1, "无重复图片");
        }

        private void btn_CompareFast_Click(object sender, EventArgs e)
        {
            chekImgss(txt_imagePath.Text);
        }

        public static List<Dictionary<string, string>> chekImgss(string filePath)
        {
            List<Dictionary<string, string>> liststr = new List<Dictionary<string, string>>();
            DirectoryInfo dir = new DirectoryInfo(filePath);
            FileInfo[] files = dir.GetFiles();
            int tmp = 0;
            foreach (FileInfo fileInfo in files)
            {
                Dictionary<string, string> dic = new Dictionary<string, string>();
                string ex = fileInfo.Extension;
                if (ex == ".jpg" || ex == ".png")
                {
                    MemoryStream ms1 = new MemoryStream();
                    Image image2 = Image.FromFile(filePath + "\\" + fileInfo.Name);
                    image2.Save(ms1, System.Drawing.Imaging.ImageFormat.Jpeg);

                    string imgBase64 = Convert.ToBase64String(ms1.ToArray());
                    dic["base64"] = imgBase64;
                    dic["imgName"] = fileInfo.Name;
                    liststr.Add(dic);
                    ms1.Close();
                    ms1.Dispose();
                    image2.Dispose();
                    tmp++;
                    ShowMsg.showMsg(_listbox, tmp.ToString());
                }
            }
            return liststr;
        }


        
    }
}
